/* * Copyright (C) 2018-2020 Lightbend Inc. */ package akka.stream.scaladsl import akka.stream.testkit.{ StreamSpec, TestPublisher } import akka.stream.{ AbruptTerminationException, ActorMaterializer, ActorMaterializerSettings } import com.github.ghik.silencer.silent import scala.collection.immutable import scala.concurrent.{ Await, Future } @silent class TakeLastSinkSpec extends StreamSpec { val settings = ActorMaterializerSettings(system).withInputBuffer(initialSize = 2, maxSize = 16) implicit val mat: ActorMaterializer = ActorMaterializer(settings) "Sink.takeLast" must { "return the last 3 elements" in { val input = 1 to 6 val future: Future[immutable.Seq[Int]] = Source(input).runWith(Sink.takeLast(3)) val result: immutable.Seq[Int] = Await.result(future, remainingOrDefault) result should be(Seq(4, 5, 6)) } "return top three student based on GPA correctly" in { implicit val ex = system.dispatcher //#takeLast-operator-example case class Student(name: String, gpa: Double) val students = List( Student("Alison", 4.7), Student("Adrian", 3.1), Student("Alexis", 4), Student("Benita", 2.1), Student("Kendra", 4.2), Student("Jerrie", 4.3)).sortBy(_.gpa) val sourceOfStudents = Source(students) val result: Future[Seq[Student]] = sourceOfStudents.runWith(Sink.takeLast(3)) result.foreach { topThree => println("#### Top students ####") topThree.reverse.foreach { s => println(s"Name: ${s.name}, GPA: ${s.gpa}") } } /* #### Top students #### Name: Alison, GPA: 4.7 Name: Jerrie, GPA: 4.3 Name: Kendra, GPA: 4.2 */ //#takeLast-operator-example result.futureValue shouldEqual students.takeRight(3) } "return the number of elements taken when the stream completes" in { val input = 1 to 4 val future: Future[immutable.Seq[Int]] = Source(input).runWith(Sink.takeLast(5)) val result: immutable.Seq[Int] = Await.result(future, remainingOrDefault) result should be(Seq(1, 2, 3, 4)) } "fail future when stream abruptly terminated" in { val mat = ActorMaterializer() val probe = TestPublisher.probe() val future: Future[immutable.Seq[Int]] = Source.fromPublisher(probe).runWith(Sink.takeLast(2))(mat) mat.shutdown() future.failed.futureValue shouldBe an[AbruptTerminationException] } "yield empty seq for empty stream" in { val future: Future[immutable.Seq[Int]] = Source.empty[Int].runWith(Sink.takeLast(3)) val result: immutable.Seq[Int] = Await.result(future, remainingOrDefault) result should be(Seq.empty) } "return the last element" in { val input = 1 to 4 val future: Future[immutable.Seq[Int]] = Source(input).runWith(Sink.takeLast(1)) val result: immutable.Seq[Int] = Await.result(future, remainingOrDefault) result should be(Seq(4)) } } }