pekko/akka-docs/src/test/scala/docs/stream/StreamTestKitDocSpec.scala

160 lines
4.2 KiB
Scala
Raw Normal View History

/*
* Copyright (C) 2015-2020 Lightbend Inc. <https://www.lightbend.com>
2015-04-24 11:45:03 +03:00
*/
2015-04-24 11:45:03 +03:00
package docs.stream
2015-06-19 10:03:55 +03:00
import scala.util._
import scala.concurrent.duration._
import scala.concurrent._
2020-09-08 15:10:21 +02:00
import akka.Done
import akka.stream._
import akka.stream.scaladsl._
import akka.stream.testkit.scaladsl._
import akka.testkit.{ AkkaSpec, TestProbe }
2015-06-19 10:03:55 +03:00
import akka.pattern
2015-04-24 11:45:03 +03:00
class StreamTestKitDocSpec extends AkkaSpec {
2015-06-19 10:03:55 +03:00
"strict collection" in {
//#strict-collection
val sinkUnderTest = Flow[Int].map(_ * 2).toMat(Sink.fold(0)(_ + _))(Keep.right)
2015-04-24 11:45:03 +03:00
2015-06-19 10:03:55 +03:00
val future = Source(1 to 4).runWith(sinkUnderTest)
val result = Await.result(future, 3.seconds)
2015-06-19 10:03:55 +03:00
assert(result == 20)
//#strict-collection
2015-04-24 11:45:03 +03:00
}
2015-06-19 10:03:55 +03:00
"grouped part of infinite stream" in {
//#grouped-infinite
import system.dispatcher
import akka.pattern.pipe
2015-06-19 10:03:55 +03:00
val sourceUnderTest = Source.repeat(1).map(_ * 2)
val future = sourceUnderTest.take(10).runWith(Sink.seq)
val result = Await.result(future, 3.seconds)
2015-06-19 10:03:55 +03:00
assert(result == Seq.fill(10)(2))
//#grouped-infinite
}
"folded stream" in {
//#folded-stream
val flowUnderTest = Flow[Int].takeWhile(_ < 5)
val future = Source(1 to 10).via(flowUnderTest).runWith(Sink.fold(Seq.empty[Int])(_ :+ _))
val result = Await.result(future, 3.seconds)
2015-06-19 10:03:55 +03:00
assert(result == (1 to 4))
//#folded-stream
}
"pipe to test probe" in {
//#pipeto-testprobe
import system.dispatcher
import akka.pattern.pipe
2015-06-19 10:03:55 +03:00
val sourceUnderTest = Source(1 to 4).grouped(2)
val probe = TestProbe()
sourceUnderTest.runWith(Sink.seq).pipeTo(probe.ref)
probe.expectMsg(3.seconds, Seq(Seq(1, 2), Seq(3, 4)))
2015-06-19 10:03:55 +03:00
//#pipeto-testprobe
}
"sink actor ref" in {
//#sink-actorref
case object Tick
val sourceUnderTest = Source.tick(0.seconds, 200.millis, Tick)
2015-06-19 10:03:55 +03:00
val probe = TestProbe()
2020-09-08 15:10:21 +02:00
val cancellable = sourceUnderTest
.to(Sink.actorRef(probe.ref, onCompleteMessage = "completed", onFailureMessage = _ => "failed"))
.run()
2015-06-19 10:03:55 +03:00
probe.expectMsg(1.second, Tick)
2020-09-08 15:10:21 +02:00
probe.expectNoMessage(100.millis)
probe.expectMsg(3.seconds, Tick)
2015-06-19 10:03:55 +03:00
cancellable.cancel()
probe.expectMsg(3.seconds, "completed")
2015-06-19 10:03:55 +03:00
//#sink-actorref
}
"source actor ref" in {
//#source-actorref
val sinkUnderTest = Flow[Int].map(_.toString).toMat(Sink.fold("")(_ + _))(Keep.right)
2020-09-08 15:10:21 +02:00
val (ref, future) = Source
.actorRef(
completionMatcher = {
case Done =>
CompletionStrategy.draining
},
// Never fail the stream because of a message:
failureMatcher = PartialFunction.empty,
bufferSize = 8,
overflowStrategy = OverflowStrategy.fail)
.toMat(sinkUnderTest)(Keep.both)
.run()
2015-06-19 10:03:55 +03:00
ref ! 1
ref ! 2
ref ! 3
2020-09-08 15:10:21 +02:00
ref ! Done
2015-06-19 10:03:55 +03:00
val result = Await.result(future, 3.seconds)
2015-06-19 10:03:55 +03:00
assert(result == "123")
//#source-actorref
}
2015-04-24 11:45:03 +03:00
2015-06-19 10:03:55 +03:00
"test sink probe" in {
2015-04-24 11:45:03 +03:00
//#test-sink-probe
2015-06-19 10:03:55 +03:00
val sourceUnderTest = Source(1 to 4).filter(_ % 2 == 0).map(_ * 2)
sourceUnderTest.runWith(TestSink[Int]()).request(2).expectNext(4, 8).expectComplete()
2015-04-24 11:45:03 +03:00
//#test-sink-probe
}
2015-06-19 10:03:55 +03:00
"test source probe" in {
//#test-source-probe
val sinkUnderTest = Sink.cancelled
2019-03-11 10:38:24 +01:00
TestSource.probe[Int].toMat(sinkUnderTest)(Keep.left).run().expectCancellation()
2015-06-19 10:03:55 +03:00
//#test-source-probe
}
"injecting failure" in {
//#injecting-failure
val sinkUnderTest = Sink.head[Int]
2019-03-11 10:38:24 +01:00
val (probe, future) = TestSource.probe[Int].toMat(sinkUnderTest)(Keep.both).run()
2015-06-19 10:03:55 +03:00
probe.sendError(new Exception("boom"))
2020-09-08 15:10:21 +02:00
assert(future.failed.futureValue.getMessage == "boom")
2015-06-19 10:03:55 +03:00
//#injecting-failure
}
"test source and a sink" in {
import system.dispatcher
//#test-source-and-sink
val flowUnderTest = Flow[Int].mapAsyncUnordered(2) { sleep =>
2015-06-19 10:03:55 +03:00
pattern.after(10.millis * sleep, using = system.scheduler)(Future.successful(sleep))
}
val (pub, sub) = TestSource.probe[Int].via(flowUnderTest).toMat(TestSink[Int]())(Keep.both).run()
2015-06-19 10:03:55 +03:00
sub.request(n = 3)
pub.sendNext(3)
pub.sendNext(2)
pub.sendNext(1)
sub.expectNextUnordered(1, 2, 3)
pub.sendError(new Exception("Power surge in the linear subroutine C-47!"))
val ex = sub.expectError()
2015-06-19 10:03:55 +03:00
assert(ex.getMessage.contains("C-47"))
//#test-source-and-sink
}
2015-04-24 11:45:03 +03:00
}