Skip to content

Commit

Permalink
Improved error messages for harness-zio-mock errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Kalin-Rudnicki committed Mar 21, 2024
1 parent 60d91ff commit b09c5aa
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ abstract class Mock[Z](implicit rTag: Tag[Z]) { myMock =>
case _ => false
}

final def namePart: String =
myCapability.getClass.getSimpleName.stripSuffix("$")

final def name: String =
s"${myMock.name}<${myCapability.getClass.getSimpleName.stripSuffix("$")}>"
s"${myMock.name}<$namePart>"

// =====| |=====

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,59 @@ import harness.zio.mock.*
import harness.zio.mock.Types.*

sealed trait MockError extends Throwable {
import MockError.{attnStar, hintHeader}

// TODO (KR) : colorize?
override final def getMessage: String = this match {
case MockError.UnexpectedCall(givenCapability, expectations) =>
val expStr = expectations match {
case Nil => "\n (expected no more calls)"
case _ => s"\n expected calls:${expectations.map(e => s"\n - ${e.name}").mkString}"
override final def getMessage: String = {
val baseMessage: String =
this match {
case MockError.UnexpectedCall(givenCapability, expectations) =>
val seededCallsStr = expectations match {
case Nil => "\n (expected no more calls)"
case _ => expectations.map(e => s"\n - ${if (e == givenCapability) attnStar else ""}${e.name}").mkString
}

expectations.indexOf(givenCapability) match {
case -1 =>
s"""Unexpected call to capability ${givenCapability.name}
| currently seeded calls:$seededCallsStr
|$hintHeader
| It looks like you have no upcoming seeded calls to ${givenCapability.name}.
| Either your code called this function when you didn't want it to, or you forgot to seed this call.""".stripMargin
case nextIndex =>
val unexpected = expectations.take(nextIndex)
s"""Unexpected call to capability ${givenCapability.name}
| currently seeded calls:$seededCallsStr
|$hintHeader
| It looks like you seeded a call to ${givenCapability.name} later on.
| This most likely means that you did not account for the following calls: ${unexpected.map(e => s"\n - ${e.name}").mkString}
| Either your code called these functions when you didn't want it to, or you forgot to seed these calls.""".stripMargin
}
case MockError.UnsatisfiedCalls(expectations) =>
s"""Unsatisfied seeded calls:${expectations.toList.map(e => s"\n - ${e.name}").mkString}
|$hintHeader
| Tests can not exit with seeded calls that did not end up being called.
| This means you either need to remove calls you didn't expect to actually be called,
| or your test is failing, because calls you expected to be made were not made.""".stripMargin
case MockError.CapabilityIsAlreadyImplemented(capability) =>
val mockImplStr = s"${capability.getMock.name}.${capability.namePart}.implement.___(___)"
s"""Capability is already implemented: ${capability.name}
|$hintHeader
| You can not implement the same capability multiple times.
| You essentially did $mockImplStr ++ $mockImplStr""".stripMargin
}
s"\n Unexpected call to capability ${givenCapability.name}$expStr"
case MockError.UnsatisfiedCalls(expectations) =>
s"\n Unsatisfied seeded calls (test can not exit with remaining expectations):${expectations.toList.map(e => s"\n - ${e.name}").mkString}"
case MockError.CapabilityIsAlreadyImplemented(capability) =>
s"\n Capability is already implemented: ${capability.name}"

s"\n$baseMessage".replaceAll("\n", "\n ")
}

override final def toString: String = getMessage

}
object MockError {

private val attnStar: String = s"${scala.io.AnsiColor.CYAN}(*)${scala.io.AnsiColor.RESET} "
private val hintHeader: String = s"${scala.io.AnsiColor.MAGENTA}<< HINT >>${scala.io.AnsiColor.RESET}"

final case class UnexpectedCall(
givenCapability: ErasedCapability,
expectations: List[ErasedCapability],
Expand Down

0 comments on commit b09c5aa

Please sign in to comment.