All Downloads are FREE. Search and download functionalities are using the official Maven repository.

intent.core.expectations.equal.scala Maven / Gradle / Ivy

The newest version!
package intent.core.expectations

import intent.core._
import scala.concurrent.Future
import scala.collection.mutable.ListBuffer
import scala.{Array, Iterable}

private def evalToEqual[T](actual: Iterable[T],
                            expected: Iterable[T],
                            expect: Expect[_],
                            actualListTypeName: String,
                            expectedListTypeName: String)
   (given
      eqq: Eq[T],
      fmt: Formatter[T]
    ): Future[ExpectationResult] =

  def emptyIterator: Iterator[T] = Seq.empty[T].iterator
  def printContents(lb: ListBuffer[String], it: Iterable[T]) =
    if it eq null then "" else lb.mkString("(", ", ", ")")

  val areSameOk = (actual eq expected) && !expect.isNegated
  if areSameOk then
    // Shortcut the logic below. This allows us to test that an infinite list is
    // equal to itself.
    return Future.successful(expect.pass)

  val actualFormatted = ListBuffer[String]()
  val expectedFormatted = ListBuffer[String]()
  val actualIterator = Option(actual).map(_.iterator).getOrElse(emptyIterator)
  val expectedIterator = Option(expected).map(_.iterator).getOrElse(emptyIterator)
  var mismatch = false
  // TODO: Handle very long / infinite collections
  while !mismatch && actualIterator.hasNext && expectedIterator.hasNext do
    val actualNext = actualIterator.next()
    val expectedNext = expectedIterator.next()
    actualFormatted += fmt.format(actualNext)
    expectedFormatted += fmt.format(expectedNext)
    if !eqq.areEqual(actualNext, expectedNext) then
      mismatch = true

  // Must check if one (but not the other) is null, since we use an empty-iterator
  // fallback above (so null gets treated as empty list above).
  val oneIsNull = (actual eq null) ^ (expected eq null)
  val hasDiff = mismatch || actualIterator.hasNext || expectedIterator.hasNext || oneIsNull
  val allGood = if expect.isNegated then hasDiff else !hasDiff

  val r = if !allGood then

    // Collect the rest of the collections, if needed
    while actualIterator.hasNext || expectedIterator.hasNext do
      if actualIterator.hasNext then actualFormatted += fmt.format(actualIterator.next())
      if expectedIterator.hasNext then expectedFormatted += fmt.format(expectedIterator.next())

    val actualStr = actualListTypeName + printContents(actualFormatted, actual)
    val expectedStr = expectedListTypeName + printContents(expectedFormatted, expected)

    val desc = if expect.isNegated then
      s"Expected $actualStr to not equal $expectedStr"
    else
      s"Expected $actualStr to equal $expectedStr"
    expect.fail(desc)
  else expect.pass
  Future.successful(r)

class EqualExpectation[T](expect: Expect[T], expected: T)
   (given eqq: Eq[T], fmt: Formatter[T]) extends Expectation

  def evaluate(): Future[ExpectationResult] =
    val actual = expect.evaluate()

    var comparisonResult = eqq.areEqual(actual, expected)
    if expect.isNegated then comparisonResult = !comparisonResult

    val r = if !comparisonResult then
      val actualStr = fmt.format(actual)
      val expectedStr = fmt.format(expected)

      val desc = if expect.isNegated then
        s"Expected $actualStr not to equal $expectedStr"
      else
        s"Expected $expectedStr but found $actualStr"
      expect.fail(desc)
    else expect.pass
    Future.successful(r)

class IterableEqualExpectation[T](expect: Expect[Iterable[T]], expected: Iterable[T])
 (given
    eqq: Eq[T],
    fmt: Formatter[T]
  ) extends Expectation

  def evaluate(): Future[ExpectationResult] =
    val actual = expect.evaluate()
    evalToEqual(actual, expected, expect, listTypeName(actual), listTypeName(expected))


class ArrayEqualExpectation[T](expect: Expect[Array[T]], expected: Iterable[T])
 (given
    eqq: Eq[T],
    fmt: Formatter[T]
  ) extends Expectation

  def evaluate(): Future[ExpectationResult] =
    val actual = expect.evaluate()
    evalToEqual(actual, expected, expect, "Array", listTypeName(expected))




© 2015 - 2024 Weber Informatics LLC | Privacy Policy