summaryrefslogtreecommitdiff
path: root/test/files/jvm/future-spec
diff options
context:
space:
mode:
Diffstat (limited to 'test/files/jvm/future-spec')
-rw-r--r--test/files/jvm/future-spec/FutureTests.scala178
-rw-r--r--test/files/jvm/future-spec/PromiseTests.scala78
-rw-r--r--test/files/jvm/future-spec/main.scala36
3 files changed, 146 insertions, 146 deletions
diff --git a/test/files/jvm/future-spec/FutureTests.scala b/test/files/jvm/future-spec/FutureTests.scala
index 7deb4929d4..5d213691df 100644
--- a/test/files/jvm/future-spec/FutureTests.scala
+++ b/test/files/jvm/future-spec/FutureTests.scala
@@ -13,15 +13,15 @@ import scala.util.{Try,Success,Failure}
object FutureTests extends MinimalScalaTest {
/* some utils */
-
+
def testAsync(s: String)(implicit ec: ExecutionContext): Future[String] = s match {
case "Hello" => future { "World" }
case "Failure" => Future.failed(new RuntimeException("Expected exception; to test fault-tolerance"))
case "NoReply" => Promise[String]().future
}
-
+
val defaultTimeout = 5 seconds
-
+
/* future specification */
"A future with custom ExecutionContext" should {
@@ -31,41 +31,41 @@ object FutureTests extends MinimalScalaTest {
t =>
ms += t
})
-
+
class ThrowableTest(m: String) extends Throwable(m)
-
+
val f1 = future[Any] {
throw new ThrowableTest("test")
}
-
+
intercept[ThrowableTest] {
Await.result(f1, defaultTimeout)
}
-
+
val latch = new TestLatch
val f2 = future {
Await.ready(latch, 5 seconds)
"success"
}
val f3 = f2 map { s => s.toUpperCase }
-
+
f2 foreach { _ => throw new ThrowableTest("dispatcher foreach") }
f2 onSuccess { case _ => throw new ThrowableTest("dispatcher receive") }
-
+
latch.open()
-
+
Await.result(f2, defaultTimeout) mustBe ("success")
-
+
f2 foreach { _ => throw new ThrowableTest("current thread foreach") }
f2 onSuccess { case _ => throw new ThrowableTest("current thread receive") }
-
+
Await.result(f3, defaultTimeout) mustBe ("SUCCESS")
-
+
val waiting = future {
Thread.sleep(1000)
}
Await.ready(waiting, 2000 millis)
-
+
ms.size mustBe (4)
//FIXME should check
}
@@ -110,24 +110,24 @@ object FutureTests extends MinimalScalaTest {
val future0 = future[Any] {
"five!".length
}
-
+
val future1 = for {
a <- future0.mapTo[Int] // returns 5
b <- async(a) // returns "10"
c <- async(7) // returns "14"
} yield b + "-" + c
-
+
val future2 = for {
a <- future0.mapTo[Int]
b <- (future { (a * 2).toString }).mapTo[Int]
- c <- future { (7 * 2).toString }
+ c <- future { (7 * 2).toString }
} yield b + "-" + c
-
+
Await.result(future1, defaultTimeout) mustBe ("10-14")
assert(checkType(future1, manifest[String]))
intercept[ClassCastException] { Await.result(future2, defaultTimeout) }
}
-
+
"support pattern matching within a for-comprehension" in {
case class Req[T](req: T)
case class Res[T](res: T)
@@ -135,44 +135,44 @@ object FutureTests extends MinimalScalaTest {
case Req(s: String) => future { Res(s.length) }
case Req(i: Int) => future { Res((i * 2).toString) }
}
-
+
val future1 = for {
Res(a: Int) <- async(Req("Hello"))
Res(b: String) <- async(Req(a))
Res(c: String) <- async(Req(7))
} yield b + "-" + c
-
+
val future2 = for {
Res(a: Int) <- async(Req("Hello"))
Res(b: Int) <- async(Req(a))
Res(c: Int) <- async(Req(7))
} yield b + "-" + c
-
+
Await.result(future1, defaultTimeout) mustBe ("10-14")
intercept[NoSuchElementException] { Await.result(future2, defaultTimeout) }
}
-
+
"recover from exceptions" in {
val future1 = Future(5)
val future2 = future1 map (_ / 0)
val future3 = future2 map (_.toString)
-
+
val future4 = future1 recover {
case e: ArithmeticException => 0
} map (_.toString)
-
+
val future5 = future2 recover {
case e: ArithmeticException => 0
} map (_.toString)
-
+
val future6 = future2 recover {
case e: MatchError => 0
} map (_.toString)
-
+
val future7 = future3 recover {
case e: ArithmeticException => "You got ERROR"
}
-
+
val future8 = testAsync("Failure")
val future9 = testAsync("Failure") recover {
case e: RuntimeException => "FAIL!"
@@ -183,7 +183,7 @@ object FutureTests extends MinimalScalaTest {
val future11 = testAsync("Failure") recover {
case _ => "Oops!"
}
-
+
Await.result(future1, defaultTimeout) mustBe (5)
intercept[ArithmeticException] { Await.result(future2, defaultTimeout) }
intercept[ArithmeticException] { Await.result(future3, defaultTimeout) }
@@ -196,23 +196,23 @@ object FutureTests extends MinimalScalaTest {
Await.result(future10, defaultTimeout) mustBe ("World")
Await.result(future11, defaultTimeout) mustBe ("Oops!")
}
-
+
"recoverWith from exceptions" in {
val o = new IllegalStateException("original")
val r = new IllegalStateException("recovered")
-
+
intercept[IllegalStateException] {
val failed = Future.failed[String](o) recoverWith {
case _ if false == true => Future.successful("yay!")
}
Await.result(failed, defaultTimeout)
} mustBe (o)
-
+
val recovered = Future.failed[String](o) recoverWith {
case _ => Future.successful("yay!")
}
Await.result(recovered, defaultTimeout) mustBe ("yay!")
-
+
intercept[IllegalStateException] {
val refailed = Future.failed[String](o) recoverWith {
case _ => Future.failed[String](r)
@@ -220,7 +220,7 @@ object FutureTests extends MinimalScalaTest {
Await.result(refailed, defaultTimeout)
} mustBe (r)
}
-
+
"andThen like a boss" in {
val q = new java.util.concurrent.LinkedBlockingQueue[Int]
for (i <- 1 to 1000) {
@@ -240,28 +240,28 @@ object FutureTests extends MinimalScalaTest {
q.clear()
}
}
-
+
"firstCompletedOf" in {
def futures = Vector.fill[Future[Int]](10) {
Promise[Int]().future
} :+ Future.successful[Int](5)
-
+
Await.result(Future.firstCompletedOf(futures), defaultTimeout) mustBe (5)
Await.result(Future.firstCompletedOf(futures.iterator), defaultTimeout) mustBe (5)
}
-
+
"find" in {
val futures = for (i <- 1 to 10) yield future {
i
}
-
+
val result = Future.find[Int](futures)(_ == 3)
Await.result(result, defaultTimeout) mustBe (Some(3))
val notFound = Future.find[Int](futures.iterator)(_ == 11)
Await.result(notFound, defaultTimeout) mustBe (None)
}
-
+
"zip" in {
val timeout = 10000 millis
val f = new IllegalStateException("test")
@@ -269,48 +269,48 @@ object FutureTests extends MinimalScalaTest {
val failed = Future.failed[String](f) zip Future.successful("foo")
Await.result(failed, timeout)
} mustBe (f)
-
+
intercept[IllegalStateException] {
val failed = Future.successful("foo") zip Future.failed[String](f)
Await.result(failed, timeout)
} mustBe (f)
-
+
intercept[IllegalStateException] {
val failed = Future.failed[String](f) zip Future.failed[String](f)
Await.result(failed, timeout)
} mustBe (f)
-
+
val successful = Future.successful("foo") zip Future.successful("foo")
Await.result(successful, timeout) mustBe (("foo", "foo"))
}
-
+
"fold" in {
val timeout = 10000 millis
def async(add: Int, wait: Int) = future {
Thread.sleep(wait)
add
}
-
+
val futures = (0 to 9) map {
idx => async(idx, idx * 20)
}
val folded = Future.fold(futures)(0)(_ + _)
Await.result(folded, timeout) mustBe (45)
-
+
val futuresit = (0 to 9) map {
idx => async(idx, idx * 20)
}
val foldedit = Future.fold(futures)(0)(_ + _)
Await.result(foldedit, timeout) mustBe (45)
}
-
+
"fold by composing" in {
val timeout = 10000 millis
def async(add: Int, wait: Int) = future {
Thread.sleep(wait)
add
}
- def futures = (0 to 9) map {
+ def futures = (0 to 9) map {
idx => async(idx, idx * 20)
}
val folded = futures.foldLeft(Future(0)) {
@@ -318,7 +318,7 @@ object FutureTests extends MinimalScalaTest {
}
Await.result(folded, timeout) mustBe (45)
}
-
+
"fold with an exception" in {
val timeout = 10000 millis
def async(add: Int, wait: Int) = future {
@@ -334,7 +334,7 @@ object FutureTests extends MinimalScalaTest {
Await.result(folded, timeout)
}.getMessage mustBe ("shouldFoldResultsWithException: expected")
}
-
+
"fold mutable zeroes safely" in {
import scala.collection.mutable.ArrayBuffer
def test(testNumber: Int) {
@@ -344,34 +344,34 @@ object FutureTests extends MinimalScalaTest {
case (l, _) => l
}
val result = Await.result(f.mapTo[ArrayBuffer[Int]], 10000 millis).sum
-
+
assert(result == 250500)
}
(1 to 100) foreach test //Make sure it tries to provoke the problem
}
-
+
"return zero value if folding empty list" in {
val zero = Future.fold(List[Future[Int]]())(0)(_ + _)
Await.result(zero, defaultTimeout) mustBe (0)
}
-
+
"shouldReduceResults" in {
def async(idx: Int) = future {
Thread.sleep(idx * 20)
idx
}
val timeout = 10000 millis
-
+
val futures = (0 to 9) map { async }
val reduced = Future.reduce(futures)(_ + _)
Await.result(reduced, timeout) mustBe (45)
-
+
val futuresit = (0 to 9) map { async }
val reducedit = Future.reduce(futuresit)(_ + _)
Await.result(reducedit, timeout) mustBe (45)
}
-
+
"shouldReduceResultsWithException" in {
def async(add: Int, wait: Int) = future {
Thread.sleep(wait)
@@ -387,14 +387,14 @@ object FutureTests extends MinimalScalaTest {
Await.result(failed, timeout)
}.getMessage mustBe ("shouldFoldResultsWithException: expected")
}
-
+
"shouldReduceThrowNSEEOnEmptyInput" in {
intercept[java.util.NoSuchElementException] {
val emptyreduced = Future.reduce(List[Future[Int]]())(_ + _)
Await.result(emptyreduced, defaultTimeout)
}
}
-
+
"shouldTraverseFutures" in {
object counter {
var count = -1
@@ -403,23 +403,23 @@ object FutureTests extends MinimalScalaTest {
count
}
}
-
+
val oddFutures = List.fill(100)(future { counter.incAndGet() }).iterator
val traversed = Future.sequence(oddFutures)
Await.result(traversed, defaultTimeout).sum mustBe (10000)
-
+
val list = (1 to 100).toList
val traversedList = Future.traverse(list)(x => Future(x * 2 - 1))
Await.result(traversedList, defaultTimeout).sum mustBe (10000)
-
+
val iterator = (1 to 100).toList.iterator
val traversedIterator = Future.traverse(iterator)(x => Future(x * 2 - 1))
Await.result(traversedIterator, defaultTimeout).sum mustBe (10000)
}
-
+
"shouldBlockUntilResult" in {
val latch = new TestLatch
-
+
val f = future {
Await.ready(latch, 5 seconds)
5
@@ -428,28 +428,28 @@ object FutureTests extends MinimalScalaTest {
val res = Await.result(f, Inf)
res + 9
}
-
+
intercept[TimeoutException] {
Await.ready(f2, 100 millis)
}
-
+
latch.open()
-
+
Await.result(f2, defaultTimeout) mustBe (14)
-
+
val f3 = future {
Thread.sleep(100)
5
}
-
+
intercept[TimeoutException] {
Await.ready(f3, 0 millis)
}
}
-
+
"run callbacks async" in {
val latch = Vector.fill(10)(new TestLatch)
-
+
val f1 = future {
latch(0).open()
Await.ready(latch(1), TestLatch.DefaultTimeout)
@@ -462,18 +462,18 @@ object FutureTests extends MinimalScalaTest {
s.length
}
for (_ <- f2) latch(4).open()
-
+
Await.ready(latch(0), TestLatch.DefaultTimeout)
-
+
f1.isCompleted mustBe (false)
f2.isCompleted mustBe (false)
-
+
latch(1).open()
Await.ready(latch(2), TestLatch.DefaultTimeout)
-
+
f1.isCompleted mustBe (true)
f2.isCompleted mustBe (false)
-
+
val f3 = f1 map {
s =>
latch(5).open()
@@ -481,17 +481,17 @@ object FutureTests extends MinimalScalaTest {
s.length * 2
}
for (_ <- f3) latch(3).open()
-
+
Await.ready(latch(5), TestLatch.DefaultTimeout)
-
+
f3.isCompleted mustBe (false)
-
+
latch(6).open()
Await.ready(latch(4), TestLatch.DefaultTimeout)
-
+
f2.isCompleted mustBe (true)
f3.isCompleted mustBe (true)
-
+
val p1 = Promise[String]()
val f4 = p1.future map {
s =>
@@ -500,23 +500,23 @@ object FutureTests extends MinimalScalaTest {
s.length
}
for (_ <- f4) latch(9).open()
-
+
p1.future.isCompleted mustBe (false)
f4.isCompleted mustBe (false)
-
+
p1 complete Success("Hello")
-
+
Await.ready(latch(7), TestLatch.DefaultTimeout)
-
+
p1.future.isCompleted mustBe (true)
f4.isCompleted mustBe (false)
-
+
latch(8).open()
Await.ready(latch(9), TestLatch.DefaultTimeout)
-
+
Await.ready(f4, defaultTimeout).isCompleted mustBe (true)
}
-
+
"should not deadlock with nested await (ticket 1313)" in {
val simple = Future() map {
_ =>
@@ -525,7 +525,7 @@ object FutureTests extends MinimalScalaTest {
Await.result(umap, Inf)
}
Await.ready(simple, Inf).isCompleted mustBe (true)
-
+
val l1, l2 = new TestLatch
val complex = Future() map {
_ =>
@@ -545,9 +545,9 @@ object FutureTests extends MinimalScalaTest {
val f = future(5).map(_ / 0)
Await.ready(f, defaultTimeout).value.get.toString mustBe expected.toString
}
-
+
}
-
+
}
diff --git a/test/files/jvm/future-spec/PromiseTests.scala b/test/files/jvm/future-spec/PromiseTests.scala
index 8e07393900..6e613bf3ec 100644
--- a/test/files/jvm/future-spec/PromiseTests.scala
+++ b/test/files/jvm/future-spec/PromiseTests.scala
@@ -13,29 +13,29 @@ object PromiseTests extends MinimalScalaTest {
import ExecutionContext.Implicits._
val defaultTimeout = Inf
-
+
/* promise specification */
-
+
"An empty Promise" should {
-
+
"not be completed" in {
val p = Promise()
p.future.isCompleted mustBe (false)
p.isCompleted mustBe (false)
}
-
+
"have no value" in {
val p = Promise()
p.future.value mustBe (None)
p.isCompleted mustBe (false)
}
-
+
"return supplied value on timeout" in {
val failure = Promise.failed[String](new RuntimeException("br0ken")).future
val otherFailure = Promise.failed[String](new RuntimeException("last")).future
val empty = Promise[String]().future
val timedOut = Promise.successful[String]("Timedout").future
-
+
Await.result(failure fallbackTo timedOut, defaultTimeout) mustBe ("Timedout")
Await.result(timedOut fallbackTo empty, defaultTimeout) mustBe ("Timedout")
Await.result(failure fallbackTo failure fallbackTo timedOut, defaultTimeout) mustBe ("Timedout")
@@ -43,47 +43,47 @@ object PromiseTests extends MinimalScalaTest {
Await.result(failure fallbackTo otherFailure, defaultTimeout)
}.getMessage mustBe ("last")
}
-
+
}
-
+
"A successful Promise" should {
val result = "test value"
val promise = Promise[String]().complete(Success(result))
promise.isCompleted mustBe (true)
futureWithResult(_(promise.future, result))
}
-
+
"A failed Promise" should {
val message = "Expected Exception"
val promise = Promise[String]().complete(Failure(new RuntimeException(message)))
promise.isCompleted mustBe (true)
futureWithException[RuntimeException](_(promise.future, message))
}
-
+
"An interrupted Promise" should {
val message = "Boxed InterruptedException"
val future = Promise[String]().complete(Failure(new InterruptedException(message))).future
futureWithException[ExecutionException](_(future, message))
}
-
+
"A NonLocalReturnControl failed Promise" should {
val result = "test value"
val future = Promise[String]().complete(Failure(new NonLocalReturnControl[String]("test", result))).future
futureWithResult(_(future, result))
}
-
+
def futureWithResult(f: ((Future[Any], Any) => Unit) => Unit) {
-
+
"be completed" in { f((future, _) => future.isCompleted mustBe (true)) }
-
+
"contain a value" in { f((future, result) => future.value mustBe (Some(Success(result)))) }
-
+
"return when ready with 'Await.ready'" in { f((future, result) => Await.ready(future, defaultTimeout).isCompleted mustBe (true)) }
-
+
"return result with 'Await.result'" in { f((future, result) => Await.result(future, defaultTimeout) mustBe (result)) }
-
+
"not timeout" in { f((future, _) => Await.ready(future, 0 millis)) }
-
+
"filter result" in {
f {
(future, result) =>
@@ -93,16 +93,16 @@ object PromiseTests extends MinimalScalaTest {
}
}
}
-
+
"transform result with map" in { f((future, result) => Await.result((future map (_.toString.length)), defaultTimeout) mustBe (result.toString.length)) }
-
+
"compose result with flatMap" in {
f { (future, result) =>
val r = for (r <- future; p <- Promise.successful("foo").future) yield r.toString + p
Await.result(r, defaultTimeout) mustBe (result.toString + "foo")
}
}
-
+
"perform action with foreach" in {
f {
(future, result) =>
@@ -111,7 +111,7 @@ object PromiseTests extends MinimalScalaTest {
Await.result(p.future, defaultTimeout) mustBe (result)
}
}
-
+
"zip properly" in {
f {
(future, result) =>
@@ -121,9 +121,9 @@ object PromiseTests extends MinimalScalaTest {
}.getMessage mustBe ("ohnoes")
}
}
-
+
"not recover from exception" in { f((future, result) => Await.result(future.recover({ case _ => "pigdog" }), defaultTimeout) mustBe (result)) }
-
+
"perform action on result" in {
f {
(future, result) =>
@@ -132,7 +132,7 @@ object PromiseTests extends MinimalScalaTest {
Await.result(p.future, defaultTimeout) mustBe (result)
}
}
-
+
"not project a failure" in {
f {
(future, result) =>
@@ -141,34 +141,34 @@ object PromiseTests extends MinimalScalaTest {
}.getMessage mustBe ("Future.failed not completed with a throwable.")
}
}
-
+
"cast using mapTo" in {
f {
(future, result) =>
Await.result(future.mapTo[Boolean].recover({ case _: ClassCastException ⇒ false }), defaultTimeout) mustBe (false)
}
}
-
+
}
def futureWithException[E <: Throwable: Manifest](f: ((Future[Any], String) => Unit) => Unit) {
-
+
"be completed" in {
f((future, _) => future.isCompleted mustBe (true))
}
-
+
"contain a value" in {
f((future, message) => {
future.value.get.failed.get.getMessage mustBe (message)
})
}
-
+
"throw not throw exception with 'Await.ready'" in {
f {
(future, message) => Await.ready(future, defaultTimeout).isCompleted mustBe (true)
}
}
-
+
"throw exception with 'Await.result'" in {
f {
(future, message) =>
@@ -177,7 +177,7 @@ object PromiseTests extends MinimalScalaTest {
}.getMessage mustBe (message)
}
}
-
+
"retain exception with filter" in {
f {
(future, message) =>
@@ -185,21 +185,21 @@ object PromiseTests extends MinimalScalaTest {
intercept[E] { Await.result(future filter (_ => false), defaultTimeout) }.getMessage mustBe (message)
}
}
-
+
"retain exception with map" in {
f {
(future, message) =>
intercept[E] { Await.result(future map (_.toString.length), defaultTimeout) }.getMessage mustBe (message)
}
}
-
+
"retain exception with flatMap" in {
f {
(future, message) =>
intercept[E] { Await.result(future flatMap (_ => Promise.successful("foo").future), defaultTimeout) }.getMessage mustBe (message)
}
}
-
+
"zip properly" in {
f {
(future, message) =>
@@ -208,18 +208,18 @@ object PromiseTests extends MinimalScalaTest {
}.getMessage mustBe (message)
}
}
-
+
"recover from exception" in {
f {
(future, message) =>
Await.result(future.recover({ case e if e.getMessage == message ⇒ "pigdog" }), defaultTimeout) mustBe ("pigdog")
}
}
-
+
"project a failure" in {
f((future, message) => Await.result(future.failed, defaultTimeout).getMessage mustBe (message))
}
-
+
"perform action on exception" in {
f {
(future, message) =>
@@ -228,7 +228,7 @@ object PromiseTests extends MinimalScalaTest {
Await.result(p.future, defaultTimeout) mustBe (message)
}
}
-
+
"always cast successfully using mapTo" in {
f {
(future, message) =>
diff --git a/test/files/jvm/future-spec/main.scala b/test/files/jvm/future-spec/main.scala
index e000431dda..132263e2e8 100644
--- a/test/files/jvm/future-spec/main.scala
+++ b/test/files/jvm/future-spec/main.scala
@@ -8,13 +8,13 @@ import java.util.concurrent.{ TimeoutException, CountDownLatch, TimeUnit }
object Test {
-
+
def main(args: Array[String]) {
FutureTests.check()
PromiseTests.check()
TryTests.check()
}
-
+
}
trait Features {
@@ -26,7 +26,7 @@ trait Features {
trait Output {
val buffer = new StringBuilder
-
+
def bufferPrintln(a: Any) = buffer.synchronized {
buffer.append(a.toString + "\n")
}
@@ -34,20 +34,20 @@ trait Output {
trait MinimalScalaTest extends Output with Features {
-
+
val throwables = mutable.ArrayBuffer[Throwable]()
-
+
def check() {
if (throwables.nonEmpty) println(buffer.toString)
}
-
+
implicit def stringops(s: String) = new {
-
+
def should[U](snippets: =>U) = {
bufferPrintln(s + " should:")
snippets
}
-
+
def in[U](snippet: =>U) = {
try {
bufferPrintln("- " + s)
@@ -60,16 +60,16 @@ trait MinimalScalaTest extends Output with Features {
throwables += e
}
}
-
+
}
-
+
implicit def objectops(obj: Any) = new {
-
+
def mustBe(other: Any) = assert(obj == other, obj + " is not " + other)
def mustEqual(other: Any) = mustBe(other)
-
+
}
-
+
def intercept[T <: Throwable: Manifest](body: =>Any): T = {
try {
body
@@ -80,7 +80,7 @@ trait MinimalScalaTest extends Output with Features {
else t.asInstanceOf[T]
}
}
-
+
def checkType[T: Manifest, S](in: Future[T], refmanifest: Manifest[S]): Boolean = manifest[T] == refmanifest
}
@@ -94,23 +94,23 @@ object TestLatch {
class TestLatch(count: Int = 1) extends Awaitable[Unit] {
private var latch = new CountDownLatch(count)
-
+
def countDown() = latch.countDown()
def isOpen: Boolean = latch.getCount == 0
def open() = while (!isOpen) countDown()
def reset() = latch = new CountDownLatch(count)
-
+
@throws(classOf[TimeoutException])
def ready(atMost: Duration)(implicit permit: CanAwait) = {
val opened = latch.await(atMost.toNanos, TimeUnit.NANOSECONDS)
if (!opened) throw new TimeoutException("Timeout of %s." format (atMost.toString))
this
}
-
+
@throws(classOf[Exception])
def result(atMost: Duration)(implicit permit: CanAwait): Unit = {
ready(atMost)
}
-
+
}