<commit_before><commit_msg>renamed file<commit_after>package almhirt.messaging

import org.scalatest._
import scala.concurrent.duration._
import scala.reflect.ClassTag
import akka.actor.ActorSystem
import almhirt.syntax.almvalidation._
import almhirt.environment._

class ActorBasedTypedMessageChannelTests extends FlatSpec with BeforeAndAfterAll with AlmhirtsystemTestkit {
  implicit val system = createTestSystem()
  implicit val atMost = FiniteDuration(1, "s")
  implicit def getUUID = java.util.UUID.randomUUID()

  override def afterAll {
    system.dispose()
  }

  private class A(val propa: Int)
  private class B(propa: Int, val propb: String) extends A(propa)

  private def getChannel[T <: AnyRef](implicit tag: ClassTag[T]): MessageChannel[T] = MessageChannel[T](java.util.UUID.randomUUID().toString())

  """A MessageChannel[A] where B <: A""" should
    """accept both As and Bs as message payloads""" in {
      val channel = getChannel[A]
      channel.post(Message(new A(1)))
      channel.post(Message(new B(1, "B")))
      channel.close()
    }

  it should """take a handler for A that will be triggered when an A is posted""" in {
    val channel = getChannel[A]
    var hitA = false
    val future = channel <-* (x => hitA = true)
    val subscription = future.awaitResult(Duration.Inf).forceResult
    channel.post(Message(new A(1)))
    subscription.dispose()
    hitA === true
    channel.close()
  }

  it should """take a handler for A that will be triggered when an B is posted""" in {
    val channel = getChannel[A]
    var hitA = false
    val future = channel <-* (x => hitA = true)
    val subscription = future.awaitResult(Duration.Inf).forceResult
    channel.post(Message(new B(1, "A")))
    subscription.dispose()
    hitA === true
    channel.close()
  }

  """A MessageChannel[B] where B <: A""" should
    """take a handler for B that will be triggered when a B is posted""" in {
      val channel = getChannel[A]
      var hitB = false
      val future = channel <-* (x => hitB = true)
      val subscription = future.awaitResult(Duration.Inf).forceResult
      channel.post(Message(new B(1, "A")))
      subscription.dispose()
      hitB === true
      channel.close()
    }

  """A MessageChannel[A] with a subchannel of MessageChannel[B] where B <: A""" should
    """trigger the handler on the parent for an A posted on the parent and not the handler on the subchannel""" in {
      val channel = getChannel[A]
      val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
      var hitA = false
      var hitB = false
      val subscriptionA = (channel <-* (x => hitA = true)).awaitResult(Duration.Inf).forceResult
      val subscriptionB = (subChannel <-* (x => hitB = true)).awaitResult(Duration.Inf).forceResult
      channel.post(Message(new A(1)))
      subscriptionA.dispose()
      subscriptionB.dispose()
      hitA === true
      hitB === false
      channel.close()
      subChannel.close()
    }

  it should """trigger only the handler on the subchannel for a B posted on the subchannel""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true)).awaitResult(Duration.Inf).forceResult
    subChannel.post(Message(new B(1, "B")))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === false
    hitB === true
    channel.close()
    subChannel.close()
  }

  it should """trigger the handler on the parent for an A posted on the parent""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true)).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new A(1)))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === true
    channel.close()
    subChannel.close()
  }

  it should """not trigger the handler on the subchannel for an A posted on the parent""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true)).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new A(1)))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitB === false
    channel.close()
    subChannel.close()
  }

  it should """not trigger the handler on the parent for an A posted on the parent when the classifier is not met""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true, x => x.payload.propa == 0)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true, x => x.payload.propb == "")).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new A(1)))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === false
    channel.close()
    subChannel.close()
  }

  it should """trigger the handler on the parent for an A posted on the parent when the classifier is met""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true, x => x.payload.propa == 1)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true, x => x.payload.propb == "")).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new A(1)))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === true
    channel.close()
    subChannel.close()
  }

  it should """not trigger the handler on the parent or the subchannelfor an B posted on the parent when the classifier is not met""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true, x => x.payload.propa == 0)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true, x => x.payload.propb == "A")).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new B(1, "B")))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === false
    hitB === false
    channel.close()
    subChannel.close()
  }

  it should """trigger the handler on the parent and the subchannel for an B posted on the parent when the classifier is met""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true, x => x.payload.propa == 1)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true, x => x.payload.propb == "B")).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new B(1, "B")))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === true
    hitB === true
    channel.close()
    subChannel.close()
  }

  it should """trigger the handler on the parent and not on the subchannel for an B posted on the parent when the classifier is met only in the parent""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true, x => x.payload.propa == 1)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true, x => x.payload.propb == "A")).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new B(1, "B")))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === true
    hitB === false
    channel.close()
    subChannel.close()
  }

  it should """not trigger the handler on the parent but on the subchannel for an B posted on the subchannel when the classifier is met only in the subchannel""" in {
    val channel = getChannel[A]
    val subChannel = channel.createSubChannel[B]("sub").awaitResult(Duration.Inf).forceResult
    var hitA = false
    var hitB = false
    val subscriptionA = (channel <-* (x => hitA = true, x => x.payload.propa == 0)).awaitResult(Duration.Inf).forceResult
    val subscriptionB = (subChannel <-* (x => hitB = true, x => x.payload.propb == "B")).awaitResult(Duration.Inf).forceResult
    channel.post(Message(new B(1, "B")))
    subscriptionA.dispose()
    subscriptionB.dispose()
    hitA === false
    hitB === true
    channel.close()
    subChannel.close()
  }
}
{'fraction_non_alphanumeric': 0.1304959930690925, 'fraction_numerical': 0.0023824994585228505, 'mean_word_length': 3.4851869839728025, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3144914', 'n_tokens_mistral': 2798, 'n_tokens_neox': 2800, 'n_words': 814}