Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions core/jvm/src/test/scala/scalaz/zio/RTSSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
interruption of raced $testInterruptedOfRaceInterruptsContestents
cancelation is guaranteed $testCancelationIsGuaranteed
interruption of unending bracket $testInterruptionOfUnendingBracket

RTS environment
provide is modular $testProvideIsModular
"""
}

Expand Down Expand Up @@ -230,8 +233,8 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
) must_=== Some(ExampleError)

def testEvalOfAttemptOfFail = Seq(
unsafeRun(IO.fail[Throwable](ExampleError).either) must_=== Left(ExampleError),
unsafeRun(IO.suspend(IO.suspend(IO.fail[Throwable](ExampleError)).either)) must_=== Left(
unsafeRun(TaskExampleError.either) must_=== Left(ExampleError),
unsafeRun(IO.suspend(IO.suspend(TaskExampleError).either)) must_=== Left(
ExampleError
)
)
Expand Down Expand Up @@ -279,7 +282,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {

def testFailOfMultipleFailingFinalizers =
unsafeRun(
IO.fail[Throwable](ExampleError)
TaskExampleError
.ensuring(IO.effectTotal(throw InterruptCause1))
.ensuring(IO.effectTotal(throw InterruptCause2))
.ensuring(IO.effectTotal(throw InterruptCause3))
Expand Down Expand Up @@ -335,7 +338,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
val e3 = new Error("e3")

val nested: Task[Int] =
IO.fail[Throwable](ExampleError)
TaskExampleError
.ensuring(IO.die(e2))
.ensuring(IO.die(e3))

Expand All @@ -359,7 +362,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
unsafeRun(IO.bracket(IO.unit)(_ => IO.unit)(_ => IO.succeedLazy[Int](42))) must_=== 42

def testBracketErrorInAcquisition =
unsafeRun(IO.bracket(IO.fail[Throwable](ExampleError))(_ => IO.unit)(_ => IO.unit)) must
unsafeRun(IO.bracket(TaskExampleError)(_ => IO.unit)(_ => IO.unit)) must
(throwA(FiberFailure(Fail(ExampleError))))

def testBracketErrorInRelease =
Expand All @@ -372,7 +375,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {

def testBracketRethrownCaughtErrorInAcquisition = {
lazy val actual = unsafeRun(
IO.absolve(IO.bracket(IO.fail[Throwable](ExampleError))(_ => IO.unit)(_ => IO.unit).either)
IO.absolve(IO.bracket(TaskExampleError)(_ => IO.unit)(_ => IO.unit).either)
)

actual must (throwA(FiberFailure(Fail(ExampleError))))
Expand All @@ -389,16 +392,16 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
def testBracketRethrownCaughtErrorInUsage = {
lazy val actual = unsafeRun(
IO.absolve(
IO.bracket(IO.unit)(_ => IO.unit)(_ => Task.fail(ExampleError): Task[Unit]).either
IO.unit.bracket_(IO.unit)(TaskExampleError).either
)
)

actual must (throwA(FiberFailure(Fail(ExampleError))))
}

def testEvalOfAsyncAttemptOfFail = {
val io1 = IO.bracket(IO.unit)(_ => AsyncUnit[Nothing])(_ => asyncExampleError[Unit])
val io2 = IO.bracket(AsyncUnit[Throwable])(_ => IO.unit)(_ => asyncExampleError[Unit])
val io1 = IO.unit.bracket_(AsyncUnit[Nothing])(asyncExampleError[Unit])
val io2 = AsyncUnit[Throwable].bracket_(IO.unit)(asyncExampleError[Unit])

unsafeRun(io1) must (throwA(FiberFailure(Fail(ExampleError))))
unsafeRun(io2) must (throwA(FiberFailure(Fail(ExampleError))))
Expand Down Expand Up @@ -585,7 +588,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
val io =
for {
promise <- Promise.make[Nothing, Unit]
fiber <- IO.bracket(promise.succeed(()) *> IO.never)(_ => IO.unit)(_ => IO.unit).fork
fiber <- IO.bracket(promise.succeed(()) <* IO.never)(_ => IO.unit)(_ => IO.unit).fork
res <- promise.await *> fiber.interrupt.timeoutTo(42)(_ => 0)(1.second)
} yield res
unsafeRun(io) must_=== 42
Expand All @@ -596,8 +599,8 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
for {
promise <- Promise.make[Nothing, Unit]
fiber <- IO
.bracketExit[Any, Nothing, Unit, Unit](promise.succeed(()) *> IO.never)((_, _) => IO.unit)(
_ => IO.unit
.bracketExit(promise.succeed(()) *> IO.never *> IO.succeed(1))((_, _: Exit[_, _]) => IO.unit)(
_ => IO.unit: IO[Nothing, Unit]
)
.fork
res <- promise.await *> fiber.interrupt.timeoutTo(42)(_ => 0)(1.second)
Expand Down Expand Up @@ -625,7 +628,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
p1 <- Promise.make[Nothing, Unit]
p2 <- Promise.make[Nothing, Unit]
fiber <- IO
.bracketExit[Any, Nothing, Unit, Unit](IO.unit)((_, _) => p2.succeed(()) *> IO.unit)(
.bracketExit(IO.unit)((_, _: Exit[_, _]) => p2.succeed(()) *> IO.unit)(
_ => p1.succeed(()) *> IO.never
)
.fork
Expand Down Expand Up @@ -702,10 +705,11 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
exitLatch <- Promise.make[Nothing, Int]
bracketed = IO
.succeed(21)
.bracketExit[Any, Nothing, Unit] {
case (r, e) if e.interrupted => exitLatch.succeed(r)
case (_, _) => IO.die(new Error("Unexpected case"))
}(a => startLatch.succeed(a) *> IO.never)
.bracketExit(
(r: Int, exit: Exit[_, _]) =>
if (exit.interrupted) exitLatch.succeed(r)
else IO.die(new Error("Unexpected case"))
)(a => startLatch.succeed(a) *> IO.never *> IO.succeed(1))
fiber <- bracketed.fork
startValue <- startLatch.await
_ <- fiber.interrupt.fork
Expand All @@ -717,6 +721,16 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
}.reduce(_ and _)
}

def testProvideIsModular = {
val zio =
(for {
v1 <- ZIO.environment[Int]
v2 <- ZIO.environment[Int].provide(2)
v3 <- ZIO.environment[Int]
} yield (v1, v2, v3)).provide(4)
unsafeRun(zio) must_=== ((4, 2, 4))
}

def testAsyncPureIsInterruptible = {
val io =
for {
Expand Down Expand Up @@ -786,7 +800,7 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
def testBracket0UseIsInterruptible = {
val io =
for {
fiber <- IO.bracketExit[Any, Nothing, Unit, Unit](IO.unit)((_, _) => IO.unit)(_ => IO.never).fork
fiber <- IO.bracketExit(IO.unit)((_, _: Exit[_, _]) => IO.unit)(_ => IO.never).fork
res <- fiber.interrupt.timeoutTo(42)(_ => 0)(1.second)
} yield res
unsafeRun(io) must_=== 0
Expand Down Expand Up @@ -1032,6 +1046,8 @@ class RTSSpec(implicit ee: ExecutionEnv) extends TestRuntime {
val InterruptCause2 = new Exception("Oh noes 2!")
val InterruptCause3 = new Exception("Oh noes 3!")

val TaskExampleError: Task[Int] = IO.fail[Throwable](ExampleError)

def asyncExampleError[A]: Task[A] =
IO.effectAsync[Throwable, A](_(IO.fail(ExampleError)))

Expand Down
2 changes: 1 addition & 1 deletion core/jvm/src/test/scala/scalaz/zio/SemaphoreSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class SemaphoreSpec(implicit ee: org.specs2.concurrent.ExecutionEnv) extends Tes
def e5 = {
val n = 1L
unsafeRun(for {
s <- Semaphore.make(n).peek(_.acquire)
s <- Semaphore.make(n).tap(_.acquire)
_ <- s.release.fork
_ <- s.acquire
} yield () must_=== (()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class StreamChunkSpec(implicit ee: org.specs2.concurrent.ExecutionEnv) extends T
StreamChunk.monadLaw1 $monadLaw1
StreamChunk.monadLaw2 $monadLaw2
StreamChunk.monadLaw3 $monadLaw3
StreamChunk.withEffect $withEffect
StreamChunk.tap $tap
StreamChunk.foldLeft $foldLeft
StreamChunk.foldLazy $foldLazy
StreamChunk.flattenChunks $flattenChunks
Expand Down Expand Up @@ -156,13 +156,13 @@ class StreamChunkSpec(implicit ee: org.specs2.concurrent.ExecutionEnv) extends T
slurp(leftStream) must_=== slurp(rightStream)
}

private def withEffect =
private def tap =
prop { (s: StreamChunk[Any, String, String]) =>
val withoutEffect = slurp(s)
var acc = List[String]()
val withEffect = slurp(s.withEffect(a => IO.effectTotal(acc ::= a)))
val tap = slurp(s.tap(a => IO.effectTotal(acc ::= a)))

(withEffect must_=== withoutEffect) and
(tap must_=== withoutEffect) and
((Success(acc.reverse) must_== withoutEffect) when withoutEffect.succeeded)
}

Expand Down
6 changes: 3 additions & 3 deletions core/jvm/src/test/scala/scalaz/zio/stream/StreamSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class StreamSpec(implicit ee: org.specs2.concurrent.ExecutionEnv)
Stream.forever $forever
Stream.scanM $mapAccumM
Stream.transduce $transduce
Stream.withEffect $withEffect
Stream.tap $tap
Stream.fromIterable $fromIterable
Stream.fromChunk $fromChunk
Stream.fromQueue $fromQueue
Expand Down Expand Up @@ -283,9 +283,9 @@ class StreamSpec(implicit ee: org.specs2.concurrent.ExecutionEnv)
unsafeRun(peeled) must_=== ((12, Success(List('3', '4'))))
}

private def withEffect = {
private def tap = {
var sum = 0
val s = Stream(1, 1).withEffect[Any, Nothing](a => IO.effectTotal(sum += a))
val s = Stream(1, 1).tap[Any, Nothing](a => IO.effectTotal(sum += a))
val slurped = slurp(s)

(slurped must_=== Success(List(1, 1))) and (sum must_=== 2)
Expand Down
4 changes: 2 additions & 2 deletions core/shared/src/main/scala/scalaz/zio/Exit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ package scalaz.zio
* An `Exit[E, A]` describes the result of executing an `IO` value. The
* result is either succeeded with a value `A`, or failed with a `Cause[E]`.
*/
sealed abstract class Exit[+E, +A] extends Product with Serializable { self =>
sealed trait Exit[+E, +A] extends Product with Serializable { self =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, why the change? I thought abstract classes generate more efficient bytecode most of the time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We dropped Scala 2.11. The main reason for abstract class is to avoid breaking backward binary compatibility on adding a method with a default implementation.

import Exit._

/**
Expand Down Expand Up @@ -158,7 +158,7 @@ object Exit extends Serializable {
final def flatten[E, A](exit: Exit[E, Exit[E, A]]): Exit[E, A] =
exit.flatMap(identity)

sealed abstract class Cause[+E] extends Product with Serializable { self =>
sealed trait Cause[+E] extends Product with Serializable { self =>
import Cause._
final def ++[E1 >: E](that: Cause[E1]): Cause[E1] =
Then(self, that)
Expand Down
14 changes: 13 additions & 1 deletion core/shared/src/main/scala/scalaz/zio/Fiber.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,26 @@ trait Fiber[+E, +A] { self =>
* Same as `zip` but discards the output of the left hand side.
*/
final def *>[E1 >: E, B](that: Fiber[E1, B]): Fiber[E1, B] =
zip(that).map(_._2)
(self zip that).map(_._2)

/**
* Named alias for `*>`.
*/
final def zipRight[E1 >: E, B](that: Fiber[E1, B]): Fiber[E1, B] =
self *> that

/**
* Same as `zip` but discards the output of the right hand side.
*/
final def <*[E1 >: E, B](that: Fiber[E1, B]): Fiber[E1, A] =
zip(that).map(_._1)

/**
* Named alias for `<*`.
*/
final def zipLeft[E1 >: E, B](that: Fiber[E1, B]): Fiber[E1, A] =
self <* that

/**
* Maps over the value the Fiber computes.
*/
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/scalaz/zio/FiberLocal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ final class FiberLocal[A] private (private val state: Ref[State[A]]) extends Ser
* Guarantees that fiber-local data is properly freed via `bracket`.
*/
final def locally[R, E, B](value: A)(use: ZIO[R, E, B]): ZIO[R, E, B] =
set(value).bracket[R, E, B](_ => empty)(_ => use)
set(value).bracket_(empty)(use)

}

Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/scalaz/zio/FunctionIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ package scalaz.zio
* In both of these examples, the `FunctionIO` program is faster because it is
* able to perform fusion of effectful functions.
*/
sealed abstract class FunctionIO[+E, -A, +B] extends Serializable { self =>
sealed trait FunctionIO[+E, -A, +B] extends Serializable { self =>

/**
* Applies the effectful function with the specified value, returning the
Expand Down
14 changes: 13 additions & 1 deletion core/shared/src/main/scala/scalaz/zio/Managed.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final case class Managed[-R, +E, +A](reserve: ZIO[R, E, Managed.Reservation[R, E
import Managed.Reservation

def use[R1 <: R, E1 >: E, B](f: A => ZIO[R1, E1, B]): ZIO[R1, E1, B] =
reserve.bracket[R1, E1, B](_.release)(_.acquire.flatMap(f))
reserve.bracket(_.release)(_.acquire.flatMap(f))

final def use_[R1 <: R, E1 >: E, B](f: ZIO[R1, E1, B]): ZIO[R1, E1, B] =
use(_ => f)
Expand Down Expand Up @@ -63,9 +63,21 @@ final case class Managed[-R, +E, +A](reserve: ZIO[R, E, Managed.Reservation[R, E
final def *>[R1 <: R, E1 >: E, A1](that: Managed[R1, E1, A1]): Managed[R1, E1, A1] =
flatMap(_ => that)

/**
* Named alias for `*>`.
*/
final def zipRight[R1 <: R, E1 >: E, A1](that: Managed[R1, E1, A1]): Managed[R1, E1, A1] =
self *> that

final def <*[R1 <: R, E1 >: E, A1](that: Managed[R1, E1, A1]): Managed[R1, E1, A] =
flatMap(r => that.map(_ => r))

/**
* Named alias for `<*`.
*/
final def zipLeft[R1 <: R, E1 >: E, A1](that: Managed[R1, E1, A1]): Managed[R1, E1, A] =
self <* that

final def zipWith[R1 <: R, E1 >: E, A1, A2](that: Managed[R1, E1, A1])(f: (A, A1) => A2): Managed[R1, E1, A2] =
flatMap(r => that.map(r1 => f(r, r1)))

Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/scalaz/zio/Promise.scala
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ object Promise {
} yield b

private[zio] object internal {
sealed abstract class State[E, A] extends Serializable with Product
sealed trait State[E, A] extends Serializable with Product
final case class Pending[E, A](joiners: List[IO[E, A] => Unit]) extends State[E, A]
final case class Done[E, A](value: IO[E, A]) extends State[E, A]
}
Expand Down
14 changes: 13 additions & 1 deletion core/shared/src/main/scala/scalaz/zio/Schedule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,24 @@ trait Schedule[-R, -A, +B] extends Serializable { self =>
final def *>[R1 <: R, A1 <: A, C](that: Schedule[R1, A1, C]): Schedule[R1, A1, C] =
(self && that).map(_._2)

/**
* Named alias for `*>`.
*/
final def zipRight[R1 <: R, A1 <: A, C](that: Schedule[R1, A1, C]): Schedule[R1, A1, C] =
self *> that

/**
* The same as `&&`, but ignores the right output.
*/
final def <*[R1 <: R, A1 <: A, C](that: Schedule[R1, A1, C]): Schedule[R1, A1, B] =
(self && that).map(_._1)

/**
* Named alias for `<*`.
*/
final def zipLeft[R1 <: R, A1 <: A, C](that: Schedule[R1, A1, C]): Schedule[R1, A1, B] =
self <* that

/**
* Returns a new schedule that continues as long as either schedule continues,
* using the minimum of the delays of the two schedules.
Expand Down Expand Up @@ -295,7 +307,7 @@ trait Schedule[-R, -A, +B] extends Serializable { self =>
* that log failures, decisions, or computed values.
*/
final def onDecision[A1 <: A](f: (A1, Schedule.Decision[State, B]) => UIO[Unit]): Schedule[R, A1, B] =
updated(update => (a, s) => update(a, s).peek(step => f(a, step)))
updated(update => (a, s) => update(a, s).tap(step => f(a, step)))

/**
* Returns a new schedule with the specified effectful modification
Expand Down
4 changes: 2 additions & 2 deletions core/shared/src/main/scala/scalaz/zio/Semaphore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ final class Semaphore private (private val state: Ref[State]) extends Serializab
final def release: UIO[Unit] = releaseN(1)

final def withPermit[R, E, A](task: ZIO[R, E, A]): ZIO[R, E, A] =
prepare(1L).bracket[R, E, A](_.release)(_.awaitAcquire *> task)
prepare(1L).bracket(_.release)(_.awaitAcquire *> task)

/**
* Acquires a specified number of permits.
Expand All @@ -73,7 +73,7 @@ final class Semaphore private (private val state: Ref[State]) extends Serializab
* Ported from @mpilquist work in cats-effects (https://github.com/typelevel/cats-effect/pull/403)
*/
final def acquireN(n: Long): UIO[Unit] =
assertNonNegative(n) *> IO.bracketExit[Any, Nothing, Acquisition, Unit](prepare(n))(cleanup)(_.awaitAcquire)
assertNonNegative(n) *> IO.bracketExit(prepare(n))(cleanup)(_.awaitAcquire)

/**
* Ported from @mpilquist work in cats-effects (https://github.com/typelevel/cats-effect/pull/403)
Expand Down
Loading